/**
 ** @author: 牛奶加咖啡
 ** @date:  2017.8.22
 ** @brief: 用户管理客户端，TCP协议交互
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "emp_manage.h"

typedef struct sockaddr SA;
char name[30];

/**
 * @brief 客户端登录
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_login(int sockfd, MSG *pmsg)
{
    printf("input name:");
    scanf("%s", pmsg->name);
    strcpy(name,pmsg->name);
    printf("input passwd:");
    scanf("%s", pmsg->pwd);

    pmsg->opr_type = L;

    send(sockfd, pmsg, sizeof(MSG), 0);

    recv(sockfd, pmsg, sizeof(MSG), 0);

    if(pmsg->opr_result == EMPLOYEE || pmsg->opr_result == MANAGER){
        puts("login success\n");
        return 0;
    }else if(pmsg->opr_result == L_NO_USER){
        printf("login failed,no user called %s\n",pmsg->name);
        return -1;
    }else if(pmsg->opr_result == L_ERROR_PWD){
        printf("login failed,error password\n");
        return -1;
    }else{
        printf("login failed...\n");
        return -1;
    }
}

/**
 * @brief 管理员操作 添加用户
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_add_usr(int sockfd, MSG *pmsg)
{
    printf("input name:");
    scanf("%s", pmsg->name);
    printf("input passwd:");
    scanf("%s", pmsg->pwd);
    printf("2：普通员工    3：管理员\n");
    printf("input role:");
    scanf("%d", &pmsg->role);
    printf("input num:");
    scanf("%d", &pmsg->num);
    printf("input addr:");
    scanf("%s", pmsg->addr);
    printf("input age:");
    scanf("%d", &pmsg->age);
    printf("input salary:");
    scanf("%lf", &pmsg->salary);

    pmsg->opr_type = A;

    send(sockfd, pmsg, sizeof(MSG), 0);
    recv(sockfd, pmsg, sizeof(MSG), 0);

    if(pmsg->opr_result == SUCCESS){
        puts("add usr success\n");
        return 0;
    }else{
        printf("add usr fail\n");
        return -1;
    }
}

/**
 * @brief 管理员操作 删除用户
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_del_usr(int sockfd, MSG *pmsg)
{
    printf("input name:");
    scanf("%s", pmsg->name);

    pmsg->opr_type = D;

    send(sockfd, pmsg, sizeof(MSG), 0);
    recv(sockfd, pmsg, sizeof(MSG), 0);

    if(pmsg->opr_result == SUCCESS){
        puts("delete usr success\n");
        return 0;
    }else{
        printf("delete usr fail\n");
        return -1;
    }
}

/**
 * @brief 管理员操作 更改用户
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_change_usr(int sockfd, MSG *pmsg)
{
    int input;
    char cleanbuf[64];
    bzero(pmsg,sizeof(MSG));

    printf("input name:");
    scanf("%s", pmsg->name);

    pmsg->opr_type = M_USER;

    while(1)
    {
        printf("*******************************************************\n");
        printf("* 1: user role    2: user addr     3:user age         *\n");
        printf("* 4: user salary                   5:change and quit  *\n");
        printf("*******************************************************\n");
        printf("please choose : ");

        //获取用户输入
        if(scanf("%d", &input) == 0){
            fgets(cleanbuf, 64, stdin);  //类型错误需要重新清除输入缓冲区
            continue;
        }

        switch(input)
        {
            case 1:
                printf("input role(2:普通员工，3：管理员):");
                scanf("%d", &pmsg->role);
                break;

            case 2:
                printf("input addr:");
                scanf("%s", pmsg->addr);
                break;

            case 3:
                printf("input age:");
                scanf("%d", &pmsg->age);
                break;

            case 4:
                printf("input salary:");
                scanf("%lf", &pmsg->salary);
                break;

            case 5:
                send(sockfd, pmsg, sizeof(MSG), 0);
                recv(sockfd, pmsg, sizeof(MSG), 0);

                if(pmsg->opr_result == SUCCESS){
                    puts("change usr information success\n");
                    return 0;
                }else{
                    printf("change usr information fail\n");
                    return -1;
                }
                break;
        }
    }
}

/**
 * @brief 管理员操作 查询用户
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_query_usr(int sockfd, MSG *pmsg)
{
    printf("input name:");
    scanf("%s", pmsg->name);

    pmsg->opr_type = Q;

    send(sockfd, pmsg, sizeof(MSG), 0);
    recv(sockfd, pmsg, sizeof(MSG), 0);

    printf("name  :%s\n",pmsg->name);
    printf("role  :%d\n",pmsg->role);
    printf("num   :%d\n",pmsg->num);
    printf("addr  :%s\n",pmsg->addr);
    printf("age   :%d\n",pmsg->age);
    printf("salary:%.2lf\n",pmsg->salary);

    if(pmsg->opr_result == SUCCESS){
        puts("query usr success\n");
        return 0;
    }else{
        printf("query usr fail\n");
        return -1;
    }
}

/**
 * @brief 用户操作 修改个人信息：地址，年龄
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_chage_self(int sockfd, MSG *pmsg)
{
    int input;
    char cleanbuf[64];
    bzero(pmsg,sizeof(MSG));
    strcpy(pmsg->name,name);

    pmsg->opr_type = M_USER;

    while(1)
    {
        printf("*****************************************\n");
        printf("* 1: addr    2:age    3:change and quit *\n");
        printf("*****************************************\n");
        printf("please choose change item : ");

        //获取用户输入
        if(scanf("%d", &input) == 0){
            fgets(cleanbuf, 64, stdin);  //类型错误需要重新清除输入缓冲区
            continue;
        }

        switch(input)
        {
            case 1:
                printf("input addr:");
                scanf("%s", pmsg->addr);
                break;
            case 2:
                printf("input age:");
                scanf("%d", &pmsg->age);
                break;
            case 3:
                send(sockfd, pmsg, sizeof(MSG), 0);
                recv(sockfd, pmsg, sizeof(MSG), 0);
                if(pmsg->opr_result == SUCCESS){
                    puts("change usr information success\n");
                    return 0;
                }else{
                    printf("change usr information fail\n");
                    return -1;
                }
                break;
        }
    }
}

/**
 * @brief 用户操作 改密码
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_chage_code(int sockfd, MSG *pmsg)
{
    printf("input new passwd:");
    scanf("%s", pmsg->pwd);

    pmsg->opr_type = M_PWD;

    send(sockfd, pmsg, sizeof(MSG), 0);
    recv(sockfd, pmsg, sizeof(MSG), 0);

    if(pmsg->opr_result == SUCCESS)
    {
        printf("usr code is changed successfully\n");
        return 0;
    }else if(pmsg->opr_result == FAIL)
    {
        printf("usr code change failed \n");
        return -1;
    }
}

/**
 * @brief 用户操作 查询用户信息
 * @param sockfd 客户端fd
 * @param pmsg 信息结构体指针
 * @return 0成功 -1失败
 */
int do_query_self(int sockfd, MSG *pmsg)
{
    pmsg->opr_type = QA;

    send(sockfd, pmsg, sizeof(MSG), 0);
    recv(sockfd, pmsg, sizeof(MSG), 0);

    if(pmsg->opr_result == SUCCESS)
    {
        printf("following is usrinfo\n");
        printf("usr name  : %s\n",pmsg->name);
        printf("usr num   : %d\n",pmsg->num);
        printf("usr age   : %d\n",pmsg->age);
        printf("usr addr  : %s\n",pmsg->addr);
        printf("usr salary: %.2lf\n",pmsg->salary);
        return 0;
    }else if(pmsg->opr_result == FAIL)
    {
        printf("query failed\n");
        return -1;
    }
}

int main(int argc, char *argv[])
{
    int sockfd=-1;
    struct sockaddr_in servaddr;
    MSG msg;  //发送 报纸

    if(argc != 3)  //测试命令输入情况
    {
        printf("Usage：%s <server_ip> <server_port>\n",argv[0]);
        exit(-1);
    }

    if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)  //创建客户端socket
    {
        perror("fail to socket!");
        exit(-1);
    }

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = PF_INET;
    servaddr.sin_port = htons(atoi(argv[2]));
    servaddr.sin_addr.s_addr =inet_addr(argv[1]);

    if(connect(sockfd,(SA *)&servaddr,sizeof(servaddr)) < 0)  //连接服务器
    {
        perror("faile to connect\n");
        exit(-1);
    }

    while(do_login(sockfd,&msg));  //登陆界面

    int input;
    char cleanbuf[64];

    if(msg.opr_result == MANAGER){  //管理员界面
        while(1)
        {
            printf("************************************************\n");
            printf("* 1: add user   2: del usr    3: chage usr info*\n");
            printf("* 4: query usr info           5: quit          *\n");
            printf("************************************************\n");
            printf("please choose : ");

            if(scanf("%d", &input) == 0){  //获取用户输入
                fgets(cleanbuf, 64, stdin);  //类型错误需要重新清除输入缓冲区
                continue;
            }

            switch(input)
            {
                case 1:
                    do_add_usr(sockfd,&msg);
                    break;
                case 2:
                    do_del_usr(sockfd,&msg);
                    break;
                case 3:
                    do_change_usr(sockfd,&msg);
                    break;
                case 4:
                    do_query_usr(sockfd,&msg);
                    break;
                case 5:
                    exit(0);
            }
        }
    }else if(msg.opr_result == EMPLOYEE){  //普通用户界面
        while(1)
        {
            printf("*************************************************************************\n");
            printf("* 1: change usr info   2: query usr info  3: change usr code   4: quit  *\n");
            printf("*************************************************************************\n");
            printf("please choose : ");

            if(scanf("%d", &input) == 0){   //获取用户输入
                fgets(cleanbuf, 64, stdin);  //类型错误需要重新清除输入缓冲区
                continue;
            }

            switch(input)
            {
                case 1:
                    do_chage_self(sockfd,&msg);
                    break;
                case 2:
                    do_query_self(sockfd,&msg);
                    break;
                case 3:
                    do_chage_code(sockfd,&msg);
                    break;
                case 4:
                    exit(0);
            }
        }
    }
}
